﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: LGPL, Software Libre	*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using ESF.Object.XmlRepresenter;
using ESF.General;
using ESF.General.Text;

#endregion


namespace ESF.Object.SolutionGenerator.Services.Core
{
	internal static class EntityGenerator
	{
		#region Funciones para generar la clase
		
		internal static void GenerateClass (TextWriter ptxtWriter, string pstrBaseNamespace, string pstrBaseClassName, XmlObject pobjObject)
		{
			XmlObject objRefObj;
			
			StringBuilder stbMemberArrays;
			StringBuilder stbMemberBasic;
			
			StringBuilder stbUseMarksXML;
			StringBuilder stbUseMarksFilter;
			StringBuilder stbUseMarksOutput;
			StringBuilder stbIsNull;
			StringBuilder stbUseMembers;
			StringBuilder stbComparisonTypeMembers;
		
		
			stbMemberArrays = new StringBuilder ();
			stbMemberBasic = new StringBuilder ();
			
			stbUseMembers = new StringBuilder ();
			stbIsNull = new StringBuilder ();
			stbUseMarksXML = new StringBuilder ();
			stbUseMarksFilter = new StringBuilder ();
			stbUseMarksOutput = new StringBuilder ();
			
			stbComparisonTypeMembers = new StringBuilder ();
		
			#region Inicializacion de Regiones de Texto
			
			stbIsNull.AppendLine ("#region Properties of IsNull Member");
			
			stbMemberArrays.Append (TextHelper.NL_2_TAB);
			stbMemberArrays.AppendLine ("#region Member Arrays");
			
			stbMemberBasic.Append (TextHelper.NL_2_TAB);
			stbMemberBasic.AppendLine ("#region Member Basics");
			
			stbUseMembers.Append (TextHelper.NL_2_TAB);
			stbUseMembers.AppendLine ("#region Use Member Marks");
			
			stbUseMarksXML.Append (TextHelper.NL_2_TAB);
			stbUseMarksXML.AppendLine ("#region Properties of Use Marks XML");
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB);
			stbUseMarksFilter.AppendLine ("#region Properties of Use Marks Filter");
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB);
			stbUseMarksOutput.AppendLine ("#region Properties of Use Marks Output");
			
			stbUseMarksXML.Append (TextHelper.NL_2_TAB);
			stbUseMarksXML.AppendLine ("public void EnableUsesXML () { this.SetUsesXML (true); }");
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB);
			stbUseMarksFilter.AppendLine ("public void EnableUsesFilter () { this.SetUsesFilter (true); }");
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB);
			stbUseMarksOutput.AppendLine ("public void EnableUsesOutput () { this.SetUsesOutput (true); }");
			
			stbUseMarksXML.Append (TextHelper.NL_2_TAB);
			stbUseMarksXML.AppendLine ("public void DisableUsesXML () { this.SetUsesXML (false); }");
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB);
			stbUseMarksFilter.AppendLine ("public void DisableUsesFilter () { this.SetUsesFilter (false); }");
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB);
			stbUseMarksOutput.AppendLine ("public void DisableUsesOutput () { this.SetUsesOutput (false); }");
			
			stbUseMarksXML.Append (TextHelper.NL_2_TAB);
			stbUseMarksXML.Append ("private void SetUsesXML (bool pblnValue)");
			stbUseMarksXML.Append (TextHelper.NL_2_TAB_CO);
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB);
			stbUseMarksFilter.Append ("private void SetUsesFilter (bool pblnValue)");
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB_CO);
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB);
			stbUseMarksOutput.Append ("private void SetUsesOutput (bool pblnValue)");
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB_CO);
			
			stbComparisonTypeMembers.Append (TextHelper.NL_2_TAB);
			stbComparisonTypeMembers.AppendLine ("#region Properties of Comparison Types (no arrays)");
			
			#endregion
		
			#region Usings
			
			ptxtWriter.WriteLine ("#region Libraries");
			ptxtWriter.WriteLine ();
			ptxtWriter.WriteLine ("using System;");
			ptxtWriter.WriteLine ("using System.IO;");
			ptxtWriter.WriteLine ("using System.Text;");
			ptxtWriter.WriteLine ("using System.Xml;");
			ptxtWriter.WriteLine ("using System.Collections.Generic;");
			ptxtWriter.WriteLine ();
			ptxtWriter.WriteLine ("using ESF.General;");
					
			SolGenerator.AddEntitiesUsings (ref ptxtWriter, pobjObject.Members);
			
			ptxtWriter.WriteLine ();
			ptxtWriter.WriteLine ("#endregion");
			ptxtWriter.WriteLine ();
			ptxtWriter.WriteLine ();
			
			#endregion
						
			ptxtWriter.Write ("namespace {0}.{1}.Entities", pstrBaseNamespace, pobjObject.SetName);
			ptxtWriter.Write (TextHelper.NL_CO);
			ptxtWriter.Write ("public class {0}{1}", pstrBaseClassName, pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_1_TAB_CO);
						
			#region Generacion del atributo ID
			
			if (pobjObject.IDType != null)
			{
				stbMemberBasic.Append (TextHelper.NL_2_TAB);
				stbMemberBasic.AppendFormat ("public {0}? ID;", pobjObject.IDType);
				stbMemberBasic.AppendLine ();
				
				stbUseMembers.AppendFormat ("public bool UseXML_ID = true;");
				stbUseMembers.AppendFormat ("public bool UseFilter_ID = true;");
				stbUseMembers.AppendFormat ("public bool UseOutput_ID = true;");		
				
				stbUseMarksXML.Append (TextHelper.NL_3_TAB);
				stbUseMarksXML.AppendFormat ("this.UseXML_ID = pblnValue;");
				stbUseMarksXML.Append (TextHelper.NL_3_TAB);
				stbUseMarksFilter.AppendFormat ("this.UseFilter_ID = pblnValue;");
				stbUseMarksFilter.Append (TextHelper.NL_3_TAB);
				stbUseMarksOutput.AppendFormat ("this.UseOutput_ID = pblnValue;");
				stbUseMarksOutput.Append (TextHelper.NL_3_TAB);
				
				stbIsNull.Append (TextHelper.NL_2_TAB);
				stbIsNull.AppendLine ("public bool IsNull_ID { get { return (this.ID == null); } }");
				
				stbComparisonTypeMembers.Append (TextHelper.NL_2_TAB);
				stbComparisonTypeMembers.AppendFormat ("public ComparisonTypes ComparisonType_ID = ComparisonTypes.Equals;");
			}
			
			#endregion
			
			#region Miembros
				
			foreach (XmlMember objMember in pobjObject.Members)
			{
				stbIsNull.Append (TextHelper.NL_2_TAB);
				stbIsNull.AppendFormat ("public bool IsNull_{0} ", objMember.Name);
				stbIsNull.Append ("{ get { return (this.");
				stbIsNull.Append (objMember.Name);
				stbIsNull.Append (" == null); } }");
				
				if (objMember.IsCustom)
				{
					objRefObj = SolGenerator.ObjectSetManager.GetObjectBy (objMember);
				
					if (objRefObj.IsArray)
					{
						stbMemberArrays.Append (TextHelper.NL_2_TAB);
						stbMemberArrays.AppendFormat ("public List<{0}> {1};", objRefObj.Type, objMember.Name);
						
						continue;
					}
				}
				
				stbComparisonTypeMembers.Append (TextHelper.NL_2_TAB);
				stbComparisonTypeMembers.AppendFormat ("public ComparisonTypes ComparisonType_{0} = ComparisonTypes.Equals;", objMember.Name);
				
				stbMemberBasic.Append (TextHelper.NL_2_TAB);
				stbMemberBasic.AppendFormat ("public {0} {1};", objMember.ApplicableDotNETType, objMember.Name);
							
				
				stbUseMembers.Append (TextHelper.NL_2_TAB);
				stbUseMembers.AppendFormat ("public bool UseXML_{0} = true;", objMember.Name);
				stbUseMembers.AppendFormat ("public bool UseFilter_{0} = true;", objMember.Name);
				stbUseMembers.AppendFormat ("public bool UseOutput_{0} = true;", objMember.Name);
				
				stbUseMarksXML.AppendFormat ("this.UseXML_{0} = pblnValue;", objMember.Name);
				stbUseMarksXML.Append (TextHelper.NL_3_TAB);
				stbUseMarksFilter.AppendFormat ("this.UseFilter_{0} = pblnValue;", objMember.Name);
				stbUseMarksFilter.Append (TextHelper.NL_3_TAB);
				stbUseMarksOutput.AppendFormat ("this.UseOutput_{0} = pblnValue;", objMember.Name);
				stbUseMarksOutput.Append (TextHelper.NL_3_TAB);
			}
			
			#endregion
			
			#region Cierre de Funciones
			
			stbUseMarksXML.Append (TextHelper.NL_2_TAB_CC);
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB_CC);
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB_CC);
			
			#endregion
			
			#region Cierre de Regiones de Texto
			
			stbIsNull.AppendLine ();
			stbIsNull.Append (TextHelper.NL_2_TAB);
			stbIsNull.AppendLine ("#endregion");
			
			stbMemberArrays.AppendLine ();
			stbMemberArrays.Append (TextHelper.NL_2_TAB);
			stbMemberArrays.AppendLine ("#endregion");
			
			stbMemberBasic.AppendLine ();
			stbMemberBasic.Append (TextHelper.NL_2_TAB);
			stbMemberBasic.AppendLine ("#endregion");
			
			stbUseMarksXML.AppendLine ();
			stbUseMarksXML.Append (TextHelper.NL_2_TAB);
			stbUseMarksXML.AppendLine ("#endregion");
			
			stbUseMarksFilter.AppendLine ();
			stbUseMarksFilter.Append (TextHelper.NL_2_TAB);
			stbUseMarksFilter.AppendLine ("#endregion");
			
			stbUseMarksOutput.AppendLine ();
			stbUseMarksOutput.Append (TextHelper.NL_2_TAB);
			stbUseMarksOutput.AppendLine ("#endregion");
			
			stbUseMembers.AppendLine ();
			stbUseMembers.Append (TextHelper.NL_2_TAB);
			stbUseMembers.AppendLine ("#endregion");
			
			stbComparisonTypeMembers.AppendLine ();
			stbComparisonTypeMembers.Append (TextHelper.NL_2_TAB);
			stbComparisonTypeMembers.AppendLine ("#endregion");
			
			#endregion
			
			ptxtWriter.WriteLine (stbIsNull.ToString ());
			ptxtWriter.WriteLine (stbMemberArrays.ToString ());
			ptxtWriter.WriteLine (stbMemberBasic.ToString ());
			ptxtWriter.WriteLine (stbUseMarksXML.ToString ());
			ptxtWriter.WriteLine (stbUseMarksFilter.ToString ());
			ptxtWriter.WriteLine (stbUseMarksOutput.ToString ());
			ptxtWriter.WriteLine (stbUseMembers.ToString ());
			ptxtWriter.WriteLine (stbComparisonTypeMembers.ToString ());
			
			#region ToXML
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#region ToXML");
			
			EntityGenerator.GenerateToXMLMethod (ref ptxtWriter, pobjObject);
			EntityGenerator.GenerateToXMLMethodSug (ref ptxtWriter, pobjObject);
			
			EntityGenerator.GenerateToXMLMethodByRef (ref ptxtWriter, pobjObject);
			EntityGenerator.GenerateToXMLMethodByRefSug (ref ptxtWriter, pobjObject);
			
			EntityGenerator.GenerateToXMLMethodForArray (ref ptxtWriter, pobjObject);
			EntityGenerator.GenerateToXMLMethodForArraySug (ref ptxtWriter, pobjObject);
			
			EntityGenerator.GenerateToXMLMethodForArrayByRef (ref ptxtWriter, pobjObject);
			EntityGenerator.GenerateToXMLMethodForArrayByRefSug (ref ptxtWriter, pobjObject);
			
			EntityGenerator.GenerateInstance (ref ptxtWriter, pobjObject);
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#endregion");
			
			#endregion
			
			#region ToString
			
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#region ToString");
			
			EntityGenerator.GenerateToString (ref ptxtWriter, pobjObject);
			EntityGenerator.GenerateToShortString (ref ptxtWriter, pobjObject);
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#endregion");
			
			#endregion
			
			EntityGenerator.GenerateValidateProperty (ref ptxtWriter, pobjObject);
			EntityGenerator.GenerateValidations (ref ptxtWriter, pobjObject);
			
			ptxtWriter.Write (TextHelper.NL_1_TAB_CC);
			ptxtWriter.Write (TextHelper.NL_CC);
			ptxtWriter.Close ();
		}
		
		#endregion
		
		
		#region Funciones de Instancias desde XML
		
		private static void GenerateInstance (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			XmlObject objRefObj;
			XmlObject objExtRefObj;
		
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#region Instances");
			
			#region Arreglo
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static List<{0}> InstanceListFromXML (XmlNode pxmlXML, string pstrOwnerName)", pobjObject.Type);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.WriteLine ("return GenericCode.InstanceListFromXML <{0}> (pxmlXML, pstrOwnerName, {0}.InstanceFromXML);", pobjObject.Type);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
			
			#endregion
			
			#region Entidad
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static {0} InstanceFromXML (XmlNode pxmlXML)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("return {0}.InstanceFromXML (pxmlXML, null);", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);
			
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static {0} InstanceFromXML (bool pblnUseBasicValidations, XmlNode pxmlXML)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("return {0}.InstanceFromXML (pblnUseBasicValidations, pxmlXML, null);", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);
			
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static {0} InstanceFromXML (XmlNode pxmlXML, string pstrOwnerName)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("return {0}.InstanceFromXML (false, pxmlXML, pstrOwnerName);", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);
			
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static {0} InstanceFromXML (bool pblnUseBasicValidations, XmlNode pxmlXML, string pstrOwnerName)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("{0} objI;", pobjObject.Name);
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("XmlHelper xmlEx;");
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_3_TAB);				
			ptxtWriter.WriteLine ("if (pxmlXML == null) { return null; }");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("xmlEx = new XmlHelper ();");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("xmlEx.EvaluatedNode = pxmlXML;");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("xmlEx.ObjectName = \"{0}\";", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("xmlEx.ObjectOwnerName = pstrOwnerName;");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("objI = new {0} ();", pobjObject.Name);
			
			foreach (XmlMember objMember in pobjObject.Members)
			{
				ptxtWriter.Write (TextHelper.NL_3_TAB);
				ptxtWriter.Write ("objI.{0} = ", objMember.Name);
			
				if (objMember.Type == ValueTypes.Custom)
				{
					objRefObj = SolGenerator.ObjectSetManager.GetObjectBy (objMember);
					
					if (objRefObj.IsArray)
					{
						objExtRefObj = SolGenerator.ObjectSetManager [objRefObj.SetName][objRefObj.Type];
						
						ptxtWriter.Write ("{0}.InstanceListFromXML (pxmlXML [\"{1}\"], xmlEx.ObjectFullName)", objExtRefObj.Name, objMember.Name);
					}
					else
					{
						ptxtWriter.Write ("{0}.InstanceFromXML (pxmlXML [\"{1}\"], xmlEx.ObjectFullName)", objMember.CustomType, objMember.Name);
					}
				}
				else
				{
					ptxtWriter.Write ("xmlEx.GetAttributeValue");
				
					if (objMember.Type == ValueTypes.Date || objMember.Type == ValueTypes.DateTime)
					{
						ptxtWriter.Write ("DateTime");
					}
					else if (objMember.Type != ValueTypes.String)
					{
						ptxtWriter.Write (objMember.Type.ToString ());
					}
					
					ptxtWriter.Write (" ({0} && pblnUseBasicValidations, \"{1}\", \"{2}\"", 
						objMember.Required.ToString ().ToLower (), objMember.NameXML, objMember.Name);
						
					if (objMember.Type == ValueTypes.String)
					{
						if (objMember.MinLength == null)
						{
							ptxtWriter.Write (", 0");
						}
						else
						{
							ptxtWriter.Write (", " + objMember.MinLength.Value);
						}
					
						if (objMember.ApplicableMaxLength == null)
						{
							ptxtWriter.Write (", 0");
						}
						else
						{
							ptxtWriter.Write (", " + objMember.ApplicableMaxLength.Value);
						}
						
						if (objMember.RegExType != null)
						{
							ptxtWriter.Write (", TextHelper.REGEX_{0}", objMember.RegExType.ToString ());
						}
						else if (objMember.RegEx != null)
						{
							ptxtWriter.Write (", @\"{0}\"", objMember.RegEx.ToString ());
						}
					}
					
					ptxtWriter.Write (")");
				}
				
				ptxtWriter.Write (";");
			}
			
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("return objI;");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);
			
			#endregion			
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#endregion");
			ptxtWriter.WriteLine ();
		}		

		
		private static void GenerateToXMLMethodSug (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public string ToXml ()", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("return this.ToXml (\"{0}\");", pobjObject.Name);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}


		private static void GenerateToXMLMethod (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public string ToXml (string pstrElementName)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.WriteLine ("XmlTextWriter xmlWriter;");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("StringBuilder stbXML;");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("stbXML = new StringBuilder ();");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("xmlWriter = new XmlTextWriter (new StringWriter (stbXML));");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("this.ToXml (ref xmlWriter, pstrElementName);");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("xmlWriter.Close ();");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("return stbXML.ToString ();");
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToXMLMethodForArraySug (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static string ToXml (List<{0}> pobjLI)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("return {0}.ToXml (pobjLI, \"{0}s\", \"{0}\");", pobjObject.Name);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToXMLMethodForArray (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static string ToXml (List<{0}> pobjLI, string pstrElementsName, string pstrElementName)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			
			ptxtWriter.WriteLine ("XmlTextWriter xmlWriter;");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("StringBuilder stbXML;");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("stbXML = new StringBuilder ();");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("xmlWriter = new XmlTextWriter (new StringWriter (stbXML));");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("{0}.ToXml (ref xmlWriter, pobjLI, pstrElementsName, pstrElementName);", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("xmlWriter.Close ();");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("return stbXML.ToString ();");
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToXMLMethodForArrayByRefSug (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static void ToXml (ref XmlTextWriter pxmlWriter, List<{0}> pobjLI)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("{0}.ToXml (ref pxmlWriter, pobjLI, \"{0}s\", \"{0}\");", pobjObject.Name);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToXMLMethodForArrayByRef (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static void ToXml (ref XmlTextWriter pxmlWriter, List<{0}> pobjLI, string pstrElementsName, string pstrElementName)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			
			ptxtWriter.Write ("if (pobjLI == null || pobjLI.Count == 0)");
			ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
			ptxtWriter.Write ("return;");
			ptxtWriter.WriteLine (TextHelper.NL_3_TAB_CC);
			
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("pxmlWriter.WriteStartElement (pstrElementsName);");
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("pxmlWriter.WriteAttributeString (\"isArray\", \"true\");");
			
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("foreach ({0} objI in pobjLI)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
			ptxtWriter.Write ("objI.ToXml (ref pxmlWriter, pstrElementName);");
			ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
			
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("pxmlWriter.WriteEndElement ();");
			
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToXMLMethodByRefSug (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public void ToXml (ref XmlTextWriter pxmlWriter)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("this.ToXml (ref pxmlWriter, \"{0}\");", pobjObject.Name);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToXMLMethodByRef (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			XmlObject objRef;
		
		
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public void ToXml (ref XmlTextWriter pxmlWriter, string pstrElementName)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			
			ptxtWriter.Write ("pxmlWriter.WriteStartElement (pstrElementName);");
			
			if (pobjObject.IDType != null)
			{
				ptxtWriter.Write (TextHelper.NL_3_TAB);
				
				if (pobjObject.IDType == IDTypes.Guid)
				{
					ptxtWriter.Write ("if (this.ID != null && this.UseXML_ID)");
				}
				else
				{
					ptxtWriter.Write ("if (this.ID > 0 && this.UseXML_ID)");
				}
				
				ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
				ptxtWriter.WriteLine ("pxmlWriter.WriteAttributeString (\"ID\", this.ID.ToString ());"); 
				ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
			}
			
			foreach (XmlMember objMember in pobjObject.NoCustomMembers)
			{
				ptxtWriter.Write (TextHelper.NL_3_TAB);
				ptxtWriter.Write ("if (!this.IsNull_{0} && this.UseXML_{0})", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
				ptxtWriter.Write ("pxmlWriter.WriteAttributeString (\"{0}\", this.{1}.ToString ());", objMember.NameXML, objMember.Name);
				ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
			}
			
			foreach (XmlMember objMember in pobjObject.CustomMembers)
			{
				objRef = SolGenerator.ObjectSetManager.GetObjectBy (objMember);
			
				ptxtWriter.Write (TextHelper.NL_3_TAB);
				
				if (objRef.IsArray)
				{
					ptxtWriter.Write ("{0}.ToXml (ref pxmlWriter, this.{1}, \"{1}\", \"{0}\");", objRef.Type, objMember.Name);
				}
				else
				{
					ptxtWriter.Write ("if (!this.IsNull_{0})", objMember.Name);
					ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
					ptxtWriter.WriteLine ("this.{0}.ToXml (ref pxmlWriter, \"{0}\");", objMember.Name); 
					ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
				}
			}

			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("pxmlWriter.WriteEndElement ();");			
			
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
		}
		
		#endregion


		#region ToString
		
		private static void GenerateToString (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public override string ToString ()");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.WriteLine ("StringBuilder stbResult;");
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("stbResult = new StringBuilder ();");
			
			foreach (XmlMember objMember in pobjObject.Members)
			{
				ptxtWriter.Write (TextHelper.NL_3_TAB);
				ptxtWriter.Write ("if (!this.IsNull_{0})", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
				ptxtWriter.Write ("stbResult.Append (this.{0}.ToString ());", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
			}
			
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("return stbResult.ToString ();");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);
		}
		
		
		private static void GenerateToShortString (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public string ToShortString ()");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.WriteLine ("StringBuilder stbResult;");
			ptxtWriter.WriteLine ();
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.WriteLine ("stbResult = new StringBuilder ();");
			
			foreach (XmlMember objMember in pobjObject.ToShortStringMembers)
			{
				ptxtWriter.Write (TextHelper.NL_3_TAB);
				ptxtWriter.Write ("if (!this.IsNull_{0})", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
				ptxtWriter.Write ("stbResult.Append (this.{0}.ToString ());", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
			}
			
			ptxtWriter.Write (TextHelper.NL_3_TAB);
			ptxtWriter.Write ("return stbResult.ToString ();");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);
		}
		
		#endregion

		
		#region Validacion

		private static void GenerateValidateProperty (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#region Validator");
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("private static Validate _Validator;");
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static Validate Validator");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("get");
			ptxtWriter.Write (TextHelper.NL_3_TAB_CO);
			ptxtWriter.Write ("if ({0}._Validator == null)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_4_TAB_CO);
			ptxtWriter.WriteLine ("{0}._Validator = new Validate ();", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_5_TAB);
			ptxtWriter.Write ("{0}._Validator.ObjectName = \"{0}\";", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_4_TAB_CC);
			ptxtWriter.Write (TextHelper.NL_4_TAB);
			ptxtWriter.Write ("return {0}._Validator;", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_3_TAB_CC);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CC);			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#endregion");
			ptxtWriter.WriteLine ();
		}
		
		
		private static void GenerateValidations (ref TextWriter ptxtWriter, XmlObject pobjObject)
		{
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#region Validations");			
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public static void ValidateFilled ({0} pobjI)", pobjObject.Name);
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("{0}.Validator.FilledObject (", pobjObject.Name);
			ptxtWriter.Write ("true, \"{0}\", pobjI);", pobjObject.GetDescription ().Label);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
			
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.Write ("public void ValidateFilledID ()");
			ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
			ptxtWriter.Write ("{0}.Validator.FilledID (this.ID);", pobjObject.Name);
			ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
			
			
			foreach (XmlMember objMember in pobjObject.CustomMembers)
			{	
				ptxtWriter.Write (TextHelper.NL_2_TAB);
				ptxtWriter.Write ("public void ValidateFilled{0} ()", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
				ptxtWriter.Write ("{0}.Validator.FilledObject (", pobjObject.Name);
				ptxtWriter.Write ("true, \"{0}\", this.{1});", objMember.GetDescription ().Label, objMember.Name);				
				ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
			}
			
			
			foreach (XmlMember objMember in pobjObject.NoCustomMembers)
			{	
				ptxtWriter.Write (TextHelper.NL_2_TAB);
				ptxtWriter.Write ("public void Validate{0} (bool pblnRequired)", objMember.Name);
				ptxtWriter.Write (TextHelper.NL_2_TAB_CO);
				ptxtWriter.Write ("{0}.Validator.Filled", pobjObject.Name);
				
				if (objMember.Type != ValueTypes.String)
				{
					ptxtWriter.Write ("Object");
				}
				// TODO: Soportar validadores reales por tipo de dato, soportar minvalue, maxvalue para otros tipos de dato tales como numeros y fechas
				
				
				ptxtWriter.Write (" (pblnRequired, \"{0}\", this.{1}", objMember.GetDescription ().Label, objMember.Name);
					
				if (objMember.Type == ValueTypes.String)
				{
					if (objMember.MinLength == null)
					{
						ptxtWriter.Write (", 0");
					}
					else
					{
						ptxtWriter.Write (", " + objMember.MinLength.Value);
					}
				
					if (objMember.ApplicableMaxLength == null)
					{
						ptxtWriter.Write (", 0");
					}
					else
					{
						ptxtWriter.Write (", " + objMember.ApplicableMaxLength.Value);
					}
					
					if (objMember.RegExType != null)
					{
						ptxtWriter.Write (", TextHelper.REGEX_{0}", objMember.RegExType.ToString ());
					}
					else if (objMember.RegEx != null)
					{
						ptxtWriter.Write (", @\"{0}\"", objMember.RegEx.ToString ());
					}
				}
				
				ptxtWriter.Write (");");
				ptxtWriter.WriteLine (TextHelper.NL_2_TAB_CC);
			}
			
			ptxtWriter.Write (TextHelper.NL_2_TAB);
			ptxtWriter.WriteLine ("#endregion");
			ptxtWriter.WriteLine ();
		}
		
		#endregion
	}
}